/*
 * This file is part of LangMan.
 *
 * LangMan is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * LangMan is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with LangMan.  If not, see <http://www.gnu.org/licenses/>.
 */

package langman.gui.tree;

import com.google.common.base.Strings;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import langman.Utils;
import langman.business.actions.common.ActionTypes;
import langman.business.actions.defaults.EditEnabled;
import langman.business.actions.defaults.RemoveEnabled;
import langman.business.data.TranslationService;
import langman.business.data.model.Key;
import langman.business.data.model.Language;
import langman.gui.ControlSelectionService;
import langman.gui.translation.TranslationsTable;
import langman.util.doping.Bean;
import langman.util.doping.Inject;

import java.text.MessageFormat;
import java.text.NumberFormat;


@SuppressWarnings("rawtypes")
@Bean
public class KeyItem extends TreeItem implements DecoratingTreeItem, SelectionAwareTreeItem, InvalidationListener, EditEnabled, RemoveEnabled, FilterableTreeItem {
    private final ControlSelectionService controlSelectionService;
    private Key key;

    private final StringProperty text = new SimpleStringProperty();
    private final StringProperty style = new SimpleStringProperty();
    private final Language referenceLanguage;

    @Inject
    public KeyItem(ControlSelectionService controlSelectionService, TranslationService translationService) {
        this.controlSelectionService = controlSelectionService;
        referenceLanguage = translationService.getReferenceLanguage();
    }

    public void setKey(Key key) {
        this.key = key;
        setValue(key);
        key.keyProperty().addListener(this);
        key.addListener(this);
        updateText();
    }

    @Override
    public void decorate(TreeCell cell) {
        cell.textProperty().bind(text);
        cell.styleProperty().bind(style);
    }

    @Override
    public void selected() {
        controlSelectionService.selectControlLater(TranslationsTable.class);
    }

    public Key getKey() {
        return key;
    }

    @Override
    public void invalidated(Observable observable) {
        updateText();
    }

    private void updateText() {
        double completeness = key.getCompleteness();
        NumberFormat numberFormat = NumberFormat.getPercentInstance();
        String referenceTranslation = formatReferenceTranslation();
        String format = numberFormat.format(completeness);
        text.set(MessageFormat.format("[{0}] {1} ({2}}", key.getKey(), referenceTranslation, format));

        String colorKey = Utils.getColorForCompleteness(completeness);
        style.set("-fx-background-color: " + colorKey + ";");
    }

    private String formatReferenceTranslation() {
        String referenceTranslation = key.getTranslation(referenceLanguage);
        if (referenceTranslation == null) {
            referenceTranslation = "no reference";
        }
        StringBuilder translationBuilder = new StringBuilder(referenceTranslation);

        if (translationBuilder.length() > 15) {
            translationBuilder.delete(15, translationBuilder.length());
            translationBuilder.append("...");
        }

        return translationBuilder.toString();
    }

    @Override
    public ActionTypes getEditAction() {
        return ActionTypes.EditKey;
    }

    @Override
    public ActionTypes getRemoveAction() {
        return ActionTypes.RemoveKey;
    }

    @Override
    public boolean filter(String filterString) {
        if (Strings.isNullOrEmpty(filterString)) {
            return true;
        }
        return Utils.containsIgnoreCase(key.getKey(), filterString);
    }
}
